package com.edou.system.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.edou.base.page.PageResult;
import com.edou.base.util.Excel2003And2007;
import com.edou.system.dao.ISysRegionDao;
import com.edou.system.dto.SysRegionCondition;
import com.edou.system.entity.SysRegion;
import com.edou.system.service.ISysRegionService;

@Service("sysRegionServiceImpl")
public class SysRegionServiceImpl implements ISysRegionService{

	private Log logger = LogFactory.getLog(getClass());
	
	@Resource(name = "sysRegionDaoImpl")
	private ISysRegionDao sysRegionDao;
	@Value("${baidu.api.ak:{NULL}}")
	private String baiduAk;
	@Autowired(required = false)
	private ServletContext servletContext;
	
	/**
	 * 查询所有省份
	 * @return
	 */
	public List<SysRegion> listProvinceAll(){
		return sysRegionDao.listProvinceAll();
	}

	/**
	 * 分页查询
	 * @param pageResult 分页对象
	 * @param condition 查询条件类
	 */
	public void listSysRegionByPage(PageResult<SysRegion> pageResult,SysRegionCondition condition){
		int rows = sysRegionDao.listSysRegionByPageCount(condition);
		pageResult.setRows(rows);
		
		RowBounds rowBounds = new RowBounds(pageResult.getCurrentPageIndex(),pageResult.getPageSize());
		List<SysRegion> list = sysRegionDao.listSysRegionByPage(rowBounds,condition);
		pageResult.setResult(list);
	}
	
	/**
	 * 查询所有区域
	 * @return
	 */
	public List<SysRegion> listSysRegionAll(){
		return sysRegionDao.listSysRegionAll();
	}
	
	/**
	 * 根据区域ID，递归查询本级及上级所有区域
	 * @param regionId
	 * @return
	 */
	public List<SysRegion> listRegionById(Long regionId) {
		List<SysRegion> list = new ArrayList<SysRegion>();
		buildParentLoop(regionId,list);
		List<SysRegion> result = new ArrayList<SysRegion>();
		for (int i = list.size()-1; i >=0; i--) {
			result.add(list.get(i));
		}
		return result;
	}
	
	/**
	 * 递归获取类型的上级集合
	 * @param cid
	 * @param categoryList
	 */
	private void buildParentLoop(Long pid, List<SysRegion> list) {
		SysRegion item = sysRegionDao.getSysRegionById(pid);
		Long parentId = item.getParentId();
		list.add(item);
		Integer level = item.getLevel();
		if(null != level && level.intValue() > 1){
			buildParentLoop(parentId,list);
		}
	}
	
	/**
	 * 查询适应门店
	 */
	public List<SysRegion> listSysRegionsByCondition(SysRegionCondition condition) {
		return sysRegionDao.listSysRegionsByCondition(condition);
	}

	/**
	 * 根据ID查询
	 * @param id 主键
	 * @return 省市区基础表
	 */
	public SysRegion getSysRegionById(Long id){
		return sysRegionDao.getSysRegionById(id);
	}

	/**
	 * 新增
	 * @param item 省市区基础表
	 */
	public void add(SysRegion item){
		if (null == item.getSort()) {
			item.setSort(0);
		}
		if (null == item.getAreaId()) {
			item.setAreaId("0");
		}
		sysRegionDao.add(item);
		//重新放入上下文
		flushSysRegion();
	}
	
	/**
	 * 批量新增（通过接口新增，所有信息都是手动新增）
	 * @param item 省市区基础表
	 */
	public void addFromAPIBatch(List<SysRegion> itemList){
		sysRegionDao.addFromAPIBatch(itemList);
	}

	/**
	 * 修改
	 * @param item 省市区基础表
	 */
	public void update(SysRegion item){
		sysRegionDao.update(item);
		//重新放入上下文
		flushSysRegion();
	}

	/**
	 * 根据ID集合批量删除
	 * @param ids ID集合
	 */
	public void delByIds(Long[] ids){
		sysRegionDao.delByIds(ids);
		//重新放入上下文
		flushSysRegion();
	}

	/**
	 * 设置热门
	 */
	public void setHot(Long[] ids,Integer status) {
		sysRegionDao.setHot(ids,status);
		List<Long> parentIdsList = Arrays.asList(ids);
		while(true){
			List<Long> childrenIdList = sysRegionDao.listSysRegionByParentId(parentIdsList);
			if (CollectionUtils.isEmpty(childrenIdList)) {
				break;
			}
			sysRegionDao.setHot(childrenIdList.toArray(new Long[childrenIdList.size()]), status);
			parentIdsList = new ArrayList<Long>();
			parentIdsList.addAll(childrenIdList);
		}
	}

	/**
	 * 分页查询大区的详情
	 */
	public void listSysRegionAreaDetailByPage(PageResult<SysRegion> pageResult,SysRegionCondition condition) {
		int rows = sysRegionDao.listSysRegionAreaDetailByPageCount(condition);
		pageResult.setRows(rows);
		
		RowBounds rowBounds = new RowBounds(pageResult.getCurrentPageIndex(),pageResult.getPageSize());
		List<SysRegion> list = sysRegionDao.listSysRegionAreaDetailByPage(rowBounds,condition);
		for (int i = 0; i < list.size(); i++) {
			if(list.get(i).getCode().length()==4 || list.get(i).getCode().length()==6 && list.get(i).getLevel()==2){
				if(list.get(i).getCode().length()==4){
					SysRegion sysRegion = sysRegionDao.getSysRegionByCode(list.get(i).getCode().substring(0,2));
					list.get(i).setCityName(sysRegion.getName());
				}
				if(list.get(i).getCode().length()==6 && list.get(i).getLevel()==3){
					SysRegion sysRegion = sysRegionDao.getSysRegionByCode(list.get(i).getCode().substring(0,4));
					list.get(i).setCityName(sysRegion.getName());
				}
			}
			if(list.get(i).getCode().length()==6 && list.get(i).getLevel()==3){
				SysRegion sysRegion2 = sysRegionDao.getSysRegionByCode(list.get(i).getCode().substring(0,2));
				SysRegion sysRegion = sysRegionDao.getSysRegionByCode(list.get(i).getCode().substring(0,4));
				list.get(i).setCityName(sysRegion2.getName()+" / "+sysRegion.getName());
			}
		}
		pageResult.setResult(list);
	}
	
	/**
	 * 批量设置区域
	 */
	public void batchFitArea(Long[] ids, String areaId) {
		sysRegionDao.batchFitArea(ids, areaId);
		List<Long> parentIdsList = Arrays.asList(ids);
		while(true){
			List<Long> childrenIdList = sysRegionDao.listSysRegionByParentId(parentIdsList);
			if (CollectionUtils.isEmpty(childrenIdList)) {
				break;
			}
			sysRegionDao.batchFitArea(childrenIdList.toArray(new Long[childrenIdList.size()]), areaId);
			parentIdsList = new ArrayList<Long>();
			parentIdsList.addAll(childrenIdList);
		}
	}

	/**
	 * 设置区域
	 */
	public void fitArea(SysRegionCondition condition) {
		sysRegionDao.fitArea(condition);
		List<Long> parentIdsList = new ArrayList<Long>();
		parentIdsList.add(condition.getRegionId());
		while(true){
			List<Long> childrenIdList = sysRegionDao.listSysRegionByParentId(parentIdsList);
			if (CollectionUtils.isEmpty(childrenIdList)) {
				break;
			}
			sysRegionDao.batchFitArea(childrenIdList.toArray(new Long[childrenIdList.size()]), condition.getAreaId());
			parentIdsList.clear();
			parentIdsList.addAll(childrenIdList);
		}
	}

	/**
	 * 移除设置的区域
	 */
	public void removeArea(SysRegionCondition condition) {
		sysRegionDao.removeArea(condition);
		List<Long> parentIdsList = new ArrayList<Long>();
		parentIdsList.add(condition.getRegionId());
		while(true){
			List<Long> childrenIdList = sysRegionDao.listSysRegionByParentId(parentIdsList);
			if (CollectionUtils.isEmpty(childrenIdList)) {
				break;
			}
			sysRegionDao.batchRemoveArea(childrenIdList.toArray(new Long[childrenIdList.size()]));
			parentIdsList.clear();
			parentIdsList.addAll(childrenIdList);
		}
	}

	/**
	 * 批量的移除设置的区域
	 */
	public void batchRemoveArea( Long[] ids) {
		sysRegionDao.batchRemoveArea(ids);
		List<Long> parentIdsList = Arrays.asList(ids);
		while(true){
			List<Long> childrenIdList = sysRegionDao.listSysRegionByParentId(parentIdsList);
			if (CollectionUtils.isEmpty(childrenIdList)) {
				break;
			}
			sysRegionDao.batchRemoveArea(childrenIdList.toArray(new Long[childrenIdList.size()]));
			parentIdsList = new ArrayList<Long>();
			parentIdsList.addAll(childrenIdList);
		}
		
	}
	/**
	 * 通过父类条件得到子类的数据
	 */
	public List<SysRegion> listSysregionByCondition(SysRegionCondition condition) {
		return sysRegionDao.listSysregionByCondition(condition);
	}

	@Override
	public List<SysRegion> listSysRegionByAreaId(String areaId) {
		return sysRegionDao.listSysRegionByAreaId(areaId);
	}

	@Override
	public SysRegion getSysRegionByCode(String code) {
		return sysRegionDao.getSysRegionByCode(code);
	}

	@Override
	public SysRegion getSysRegionByName(String name) {
		return sysRegionDao.getSysRegionByName(name);
	}

	@Override
	public SysRegion getSysRegionByAllName(String name) {
		return sysRegionDao.getSysRegionByAllName(name);
	}

	/**
	 * 查询
	 * @param parentId
	 * @param level
	 * @param name
	 * @return
	 */
	public SysRegion getSysRegionByParentIdAndLevelAndName(Long parentId, Integer level, String name) {
		return sysRegionDao.getSysRegionByParentIdAndLevelAndName(parentId, level, name);
	}

	
	/**
	 * 封装省市区JSON对象
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public JSONObject getRegionJSON(){
		JSONObject root = new JSONObject();
		//查询所有省份原始数据
		List<SysRegion> provinceList = sysRegionDao.listProvinceAll();
		//省份json
		JSONObject provinceJson = new JSONObject();
		//插叙所有省市区
		List<SysRegion> sysRegionList = sysRegionDao.listSysRegionAll();
		//封装省份数据
		for (SysRegion province : provinceList) {
			provinceJson.put(province.getId(), province.getName());
			//市json
			JSONObject cityJson = new JSONObject();
			//封装城市数据
			for (SysRegion city : sysRegionList) {
				if(province.getId().longValue() == city.getParentId().longValue()){
					cityJson.put(city.getId(), city.getName());
					//封装区json
					JSONObject districtJson = new JSONObject();
					for (SysRegion district : sysRegionList) {
						if(district.getParentId().longValue() == city.getId().longValue()){
							districtJson.put(district.getId(), district.getName());
						}
					}
					root.put(city.getId(), districtJson);
				}
			}
			root.put(province.getId(), cityJson);
		}
		root.put("86", provinceJson);
		return root;
	}

	/**
	 * 解析当前ip真实省市区
	 * @param ip
	 * @return
	 */
	public JSONObject getLocaltionJSON(String ip) {
		JSONObject root = new JSONObject();
		// 调取百度ip解析接口
		String apiUrl = "http://api.map.baidu.com/location/ip?ak={ak}&coor=bd09ll";
		apiUrl = apiUrl.replace("{ak}", baiduAk);
		
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpGet httpGet = new HttpGet(apiUrl);
		logger.debug("调取百度接口：" + apiUrl);
		CloseableHttpResponse response = null;
		String result = null;
		try{
			response = httpclient.execute(httpGet);
			result = EntityUtils.toString(response.getEntity(), "UTF-8");
			JSONParser parser = new JSONParser();
			root = (JSONObject) parser.parse(result);
			logger.debug("成功返回ip对应的地址"+result);
		}catch(Exception ex){
			logger.debug("ip地址解析出错");
			return root;
		}finally{
			if(null != response){
				try{
					response.close();
				}catch(Exception e){}
			}
		}
		return root;
	}

	/**
	 * 根据参数获得省市区
	 * @param condition
	 * @return
	 */
	@Override
	public List<SysRegion> listSysRegionByParam(SysRegionCondition condition) {
		// TODO Auto-generated method stub
		return sysRegionDao.listSysRegionByParam(condition);
	}
	
	/**
	 * 将省市区数据重新放入上下文
	 */
	protected void flushSysRegion(){
		JSONObject regionJSON = this.getRegionJSON();
		servletContext.setAttribute("regionJSON", regionJSON);
	}
	
	/**
	 * 区号导入
	 */
	@Override
	public String importXls(String path) {
		String strMessage = "";
		File f = new File(path);
//		第二行开始导入
		Integer index = 1;
		// 输入文件  
		try {
	        InputStream fis = new FileInputStream(f);  
	        Workbook wb = null;
	        if(path.contains("xlsx")){
	        	wb=new XSSFWorkbook(fis);
	        }else{
		        // 转换输入流  
		        POIFSFileSystem poifs = new POIFSFileSystem(fis);  
		        // 转换成hss格式对象  
	        	wb = new HSSFWorkbook(poifs);
	        }
	        //记录所有行  
			Excel2003And2007.ExcelReader(path);
			List<String[]> list = Excel2003And2007.getAllData(0);
			//XSSFSheet sheet = (XSSFSheet) wb.getSheetAt(0);	//取第一个sheet
			for (int j=1;j<list.size();j++){
				String[] row = list.get(j);
				int size = row.length;
				if(null != row[0] && row[0] != "") {
				String name = row[0];				// 省名称
				}
				if(row[1] == null || row[1] == "")
					continue;
				String cityName = row[1];		// 市名称
				String areaCode = row[2];		// 区号
				
				index++;
				cityName = cityName.trim();
				List<SysRegion> sysRegionList = sysRegionDao.listSysRegionAllByName(cityName);
				for(SysRegion sysRegion : sysRegionList) {
					sysRegion.setAreaCode(areaCode);
					sysRegionDao.update(sysRegion);
				}
			}
			strMessage = "";
			logger.info("导入成功");
		}catch (Exception e) {
			logger.info("出错信息："+e.getMessage(),e);
			strMessage = index.toString();
			logger.info("导入第" + index + "行失败：" + e.getMessage());
		}finally {
			FileUtils.deleteQuietly(f);
		}
		return strMessage;
	}
	
	/**
	 * 根据上级ID查询ID最大的一条数据
	 */
	@Override
	public SysRegion getSysRegionMaxIdByParentId(Long parentId) {
		return sysRegionDao.getSysRegionMaxIdByParentId(parentId);
	}
}

